package com.is.w2b;

import java.io.BufferedInputStream;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.RotatedRect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.core.TermCriteria;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgproc.Moments;
import org.opencv.*;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;

public class MainActivity<IplConvKernel> extends Activity {
	
	public LinearLayout layout;
	public ImageView iv;
	public int i;
	public CheckBox resize;
    public EditText size;
	
		
	private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
		@Override
		public void onManagerConnected(int status) {
		   switch (status) {
		       case LoaderCallbackInterface.SUCCESS:
		       {
		      // Create and set View
		     // setContentView(R.layout.activity_main);
		       } break;
		       default:
		       {
		      super.onManagerConnected(status);
		       } break;
		   }
		    }
		};
		
	public double dif(double[] buffaux){
			double aux=0.0;
			aux=buffaux[1]-buffaux[0];
			aux= (buffaux[2]-buffaux[1])+aux/2;
			return aux;
	}
	
	public boolean dentroMatriz(int i, int j, Mat img){
		
		if ( ( (i>=0) && (i<=img.rows()-1) )  && ( (j>=0) && (j<=img.cols()-1) ) ) {
			
			return true;
		}
		else 
			return false;
	}
	
	public int[] rellenarVectorI(int i){
		
		int[] aux = new int[9];
		
		aux[0]=i; aux[1]=i-1; aux[2]=i-1; aux[3]=i-2; aux[4]=i; aux[5]=i; aux[6]=i+1; aux[7]=i+1; aux[8]=i+1;
		
		return aux;
	}
	
	public int[] rellenarVectorJ(int j){
		
		int[] aux = new int[9];
		
		aux[0]=j; aux[1]=j-1; aux[2]=j; aux[3]=j+1; aux[4]=j-1; aux[5]=j+1; aux[6]=j-1; aux[7]=j; aux[8]=j+1;
		
		return aux;
	}
	
	
	
	public double[] vecinos(int i,int j, Mat img){
		
		double[] total = new double[3];
		double[] buff = new double[3];
		double totalR = 0.0;
		double totalG = 0.0;
		double totalB = 0.0;
		int[] auxI = rellenarVectorI(i);
		int[] auxJ = rellenarVectorJ(j);
		int ii = 0;
		int jj = 0;
		
		for(int k=0; k<9; k++){
			ii = auxI[k];
			jj = auxJ[k];
			
			if(dentroMatriz(ii, jj, img)){
				
				buff = img.get(ii, jj);				
				
				totalR = buff[0] + totalR;
				totalG = buff[1] + totalG;
				totalB = buff[2] + totalB;
				
			}
			
			
		}
		total[0] = totalR/9;
		total[1] = totalG/9;
		total[2] = totalB/9;
		return total;
	}
		
		
	public void mostrar(Mat mat, String titulo){
		
		
		
		Bitmap bmp = Bitmap.createBitmap(mat.cols(),mat.rows(),Bitmap.Config.ARGB_8888);
		Utils.matToBitmap(mat, bmp);
		 iv= new ImageView(this);
		iv.setImageBitmap(bmp);
		TextView tv = new TextView(this);
		tv.setText(titulo);
		layout.addView(tv,i);
		i++;
		layout.addView(iv,i);
		i++;
		
		
		
	}
	
public void gabor(){
		
		
		
		
	}
	
	
	public Bitmap kmeans(Bitmap bitmap){
		
		
    	Mat img = new Mat(bitmap.getHeight(),bitmap.getWidth(),CvType.CV_8UC3);
    	Mat img1 = new Mat(bitmap.getHeight(),bitmap.getWidth(),CvType.CV_8UC3);
    	Utils.bitmapToMat(bitmap, img1);
    	
    	double buffaux3[] = new double[3];
    	double buffaux4[] = new double[3];
    	
    	Size s= new Size(350,350);
    	Imgproc.resize(img1, img1, s);
    	Imgproc.resize(img, img, s);
    	
    	//---bucle para pasar de 4 canales que da el bitmap a tres canales q son los que qeremos
    	for(int i=0; i<img1.rows(); i++)
		{
			for(int j=0; j<img1.cols(); j++)
			{
				buffaux3 = img1.get(i, j);
				buffaux4[0]=buffaux3[0];
				buffaux4[1]=buffaux3[1];
				buffaux4[2]=buffaux3[2];
				
				
				img.put(i, j, buffaux4);
			}
		}
    	
    	/*if (resize.isChecked()){
        	//	String ss= size.toString();
        		Integer ss = Integer.valueOf(size.getText().toString());
        		Size s= new Size(ss,ss);
            	Imgproc.resize(img, img, s);
        	}*/
    	
    	
    	
    	
  	  mostrar(img,"original"); 
  	//  guardarMatriz(img, "original.txt");
    	
    
    	Mat gris = new Mat(img.size(),img.type());
    	Imgproc.cvtColor(img, gris, Imgproc.COLOR_BGR2GRAY);
    	
    //	mostrar(img,"gris");
    	
  	//    	guardarMatriz(gris,"gris.txt");
    	

    	
//    	Mat median = new Mat(img.size(),img.type());
//    	Size sm = new Size(3,3);
//    	Point p = new Point(2,2);
//    	Imgproc.blur(img, median,sm,p, Imgproc.CV_MEDIAN);
//    	
    
    	
    	Mat gauss1 = new Mat(img.size(),img.type());
    	Imgproc.GaussianBlur(img, gauss1, new Size(5,5), 1000);
    	//Log.d("canales de gauss",String.valueOf(gauss1.channels()));
    	
    	//mostrar(gauss1,"gauss10");
    	
    	//Imgproc.GaussianBlur(img, img, new Size(5,5), 2);
    	//mostrar(img,"gauss2");
    	
    	Mat sobel = new Mat(img.size(),img.type());
    	int k = img.depth();
    	Imgproc.Sobel(img, sobel, k, 0, 1);
    	//Log.d("canales de sobel",String.valueOf(sobel.channels()));
    	
    	Mat canny = new Mat(img.size(),img.type());
    	Imgproc.Canny(img, canny, 100, 99);
    	//Log.d("canales de canny",String.valueOf(canny.channels()));
    /*	
    	//guardarMatriz(median,"median.txt");

    	
    
    	Mat gauss = new Mat(median.size(),median.type());
    	 s = new Size(5,5);
    	 p = new Point(-1,-1);
    	Imgproc.blur(median, gauss,s,p, Imgproc.CV_GAUSSIAN_5x5);

    */
    	//img.reshape(3);
   // 	guardarMatriz(img,"gauss.txt");
    	
    	Size size = new Size(9,9);
      	Mat gabor1 = new Mat(img.size(),img.type());
      	Mat gabor2 = new Mat(img.size(),img.type());
    	Mat gabor3 = new Mat(img.size(),img.type());
    	Mat gabor4 = new Mat(img.size(),img.type());
    	Mat gabor5 = new Mat(img.size(),img.type());
    	Mat gabor6 = new Mat(img.size(),img.type());
    	Mat gabor7 = new Mat(img.size(),img.type());
    	Mat gabor8 = new Mat(img.size(),img.type());
        Mat gaborsuma = new Mat(img.size(),img.type());
    	//Mat gaborKernel = Imgproc.getGaborKernel(size, 3.0, -Math.PI/4, Math.PI, 10.0, Math.PI*0.5, CvType.CV_64F);
      	   											//sigma  theta lambda  gamma  psi
      	Mat gaborKernel1 = Imgproc.getGaborKernel(size, 0.56*9, 0  ,  9   , 1,    90 , CvType.CV_64F);
      	Mat gaborKernel2 = Imgproc.getGaborKernel(size, 0.56*9, 45  ,  9   , 1,    90 , CvType.CV_64F);
      	Mat gaborKernel3 = Imgproc.getGaborKernel(size, 0.56*9, 90 ,  9   , 1,    90 , CvType.CV_64F);
    	Mat gaborKernel4 = Imgproc.getGaborKernel(size, 0.56*9, 135 ,  9   , 1,    90 , CvType.CV_64F);
    	Mat gaborKernel5 = Imgproc.getGaborKernel(size, 0.56*9, 180  ,  9   , 1,    90 , CvType.CV_64F);
      	Mat gaborKernel6 = Imgproc.getGaborKernel(size, 0.56*9, 225  ,  9   , 1,    90 , CvType.CV_64F);
      	Mat gaborKernel7 = Imgproc.getGaborKernel(size, 0.56*9, 270,   9   , 1,    90 , CvType.CV_64F);
    	Mat gaborKernel8 = Imgproc.getGaborKernel(size, 0.56*9, 315 ,  9   , 1,    90 , CvType.CV_64F);
      	
    	Imgproc.filter2D(gris, gabor1, -1, gaborKernel1);
    	Imgproc.filter2D(gris, gabor2, -1, gaborKernel2);
    	Imgproc.filter2D(gris, gabor3, -1, gaborKernel3);
    	Imgproc.filter2D(gris, gabor4, -1, gaborKernel4);
    	Imgproc.filter2D(gris, gabor5, -1, gaborKernel5);
    	Imgproc.filter2D(gris, gabor6, -1, gaborKernel6);
    	Imgproc.filter2D(gris, gabor7, -1, gaborKernel7);
    	Imgproc.filter2D(gris, gabor8, -1, gaborKernel8);
    	
    	/*mostrar(gabor1,"gabor1");
    	mostrar(gabor2,"gabor2");
    	mostrar(gabor3,"gabor3");
    	mostrar(gabor4,"gabor4");
    	mostrar(gabor1,"gabor5");
    	mostrar(gabor2,"gabor6");
    	mostrar(gabor3,"gabor7");
    	mostrar(gabor4,"gabor8");*/
    	
    	Core.add(gabor1, gabor2, gabor2);
    	Core.add(gabor3, gabor4, gabor4);
    	Core.add(gabor5, gabor6, gabor6);
    	Core.add(gabor7, gabor8, gabor8);
    	Core.add(gabor2, gabor4, gabor4);
    	Core.add(gabor6, gabor8, gabor8);
    	Core.add(gabor4, gabor8, gaborsuma);
    	
    	mostrar(gaborsuma,"gaborSuma");
    	//guardarMatriz(gabor,"gabor.txt");
    	
    	Mat samples = new Mat(img.rows()*img.cols(), 8, CvType.CV_32F);  //1canal
    	//Mat samples = new Mat(img.rows()*img.cols(), 3, CvType.CV_32SC1);
			
			
			
			double buffaux[] = new double[3];
			double buffgau[] = new double[3];
			double buffsobel[] = new double[3];
			double buffcanny[] = new double[3];
			double buffvecinos[] = new double[3];
			double buffgabor[] = new double[3];
			
			
			
			int i=0;
			int j=0;
			int z=0;
			int aux=0;
			double euclidia = 0.0;
			
			Point medio = new Point(img.rows()/2,img.cols()/2);
			
			for(i=0; i<img.rows(); i++)
			{
				for(j=0; j<img.cols(); j++)
				{
					buffaux = img.get(i, j);
					buffgau = gauss1.get(i, j);
					buffsobel = sobel.get(i, j);
					buffcanny = canny.get(i, j);
					buffvecinos = vecinos(i, j, img);
					buffgabor = gaborsuma.get(i, j);
					aux = i + j*img.rows();

					
					samples.put(aux, 7, Double.valueOf(i)*0.1);
					samples.put(aux, 6, Double.valueOf(j)*0.1);
					
					samples.put(aux, 4, 2*dif(buffaux));
					//samples.put(aux, 3, buffcanny[0]);
					euclidia = Math.sqrt( (i-medio.x)*(i-medio.x)+(j-medio.y)*(j-medio.y) );
					samples.put(aux, 3, 2*euclidia);
					samples.put(aux, 5, buffgabor[0]*0.5);
					
					for(z=0; z<3; z++){
					
						//samples.put(aux, z, buffaux[z]);
						samples.put(aux, z, buffvecinos[z]);
						//samples.put(aux, z, buffgau[z]);
						//samples.put(aux, z+3, buffsobel[z]);
					
					
					
					}
				}
			}	
    	
    	//Log.d("alto",String.valueOf(bitmap.getHeight()));
    	//Log.d("canales de samples",String.valueOf(samples.channels()));
    	//Log.d("canales de img",String.valueOf(img.channels()));
    	//Log.d("canales de img1",String.valueOf(img1.channels()));
    	//guardarMatriz(samples, "samples.txt");
			
			Moments sa = new Moments();
    	
    	Mat salidaa = new Mat();
    	Mat salidaa2 = new Mat();
    	Mat salidaa3 = new Mat();
    	Mat labels = new Mat(samples.height(), 1, CvType.CV_32S);
    	Mat labels1 = new Mat(samples.height(), 1, CvType.CV_32S);
    	Mat labels2 = new Mat(samples.height(), 1, CvType.CV_32S);
    	Mat labels3 = new Mat(samples.height(), 1, CvType.CV_32S);
    //	TermCriteria mw = new TermCriteria(TermCriteria.EPS+TermCriteria.MAX_ITER,(int) 0.0001,10000);
    	TermCriteria mw = new TermCriteria(TermCriteria.COUNT+TermCriteria.EPS, 10, 1);
    	
    	Double a = Core.kmeans(samples, 2, labels, mw, 5, Core.KMEANS_RANDOM_CENTERS,salidaa);
    	//Double b = Core.kmeans(samples, 2, labels2, mw, 5, Core.KMEANS_RANDOM_CENTERS,salidaa);
    	//Double c = Core.kmeans(samples, 2, labels3, mw, 5, Core.KMEANS_RANDOM_CENTERS,salidaa);
    	
    	//double res = Math.min(a, Math.min(b, c));
    	
    	//if (res==a) labels = labels1;
    	//else if (res==b) labels = labels2;
    	//else labels = labels3;
    	
    	
    	//guardarMatriz(samples, "samplesKM.txt");
    //	guardarMatriz(salidaa, "salidaaKM.txt");
    //	guardarMatriz(labels, "labelsKM.txt");
    	//Log.d("canales de salidaa",String.valueOf(salidaa.channels()));
    	//Log.d("canales de labels",String.valueOf(labels.channels()));
    	
    	Mat nueva_imagen = new Mat(img.size(), CvType.CV_8UC3);
    	double bufflabels[] = new double[3];
    	double buffsalidaa0[] = new double[3];
    	double buffsalidaa1[] = new double[3];
    	double buffsalidaa2[] = new double[3];
    	double bufftotal[] = new double[3];
    	//double buffsalidaa[] = new double[(int) (salidaa.total() * salidaa.channels())];
    	
    	/*bufftotal[0] = 0; //azul
    	bufftotal[1] = 0;
    	bufftotal[2] = 255;
    	
    	salidaa.put(0, 0, bufftotal);
    	
    	bufftotal[0] = 255; //rojo
    	bufftotal[1] = 0;
    	bufftotal[2] = 0;
    	
    	salidaa.put(1, 0, bufftotal);*/
    	
    	int minX=img.cols();
    	int minY=img.rows();
    	int maxX=0;
    	int maxY=0;
    	
    	MatOfPoint2f points = new MatOfPoint2f();
    	
    	i = 0;
    	j = 0;
    	
    	for(i=0; i<img.rows(); i++)
			{
				for(j=0; j<img.cols(); j++)
				{
					bufflabels = labels.get(i + j*img.rows(), 0);
					int cluster_idx = (int) bufflabels[0];
					
					buffsalidaa0 = salidaa.get(cluster_idx, 0);
					buffsalidaa1 = salidaa.get(cluster_idx, 1);
					buffsalidaa2 = salidaa.get(cluster_idx, 2);
					
					bufftotal[0] = buffsalidaa0[0];
					bufftotal[1] = buffsalidaa1[0];
					bufftotal[2] = buffsalidaa2[0];
					
					nueva_imagen.put(i, j, bufftotal);
					
					
					/*if(cluster_idx==1){
						
						if (i<minX)
							minX=i;
						if (i>maxX)
							maxX=i;
						if (j<minY)
							minY=j;
						if (j>maxY)
							maxY=j;
						
					}*/
						
						/*	if(cluster_idx==1){
					
						double p[] = new double[3];
								p=bufftotal;
						points.put(i, j, p);
					}*/
				}
			}
    	
    	mostrar(nueva_imagen,"kmeans");
    	//guardarMatriz(nueva_imagen, "nueva_imagen.txt");
    	//---------------------------------------------------
    	
    /*	Mat mirarColor = nueva_imagen.clone();
    	mirarColor.submat(130, 170, 130, 170);
    	Scalar aa;
    	Scalar bb;
    	if(contarPixels(mirarColor.submat(130, 170, 130, 170)))
    	{*/
    		//----------------sacar mascara de colores rojos, q se supone son el objeto a segmentar
    //	Scalar aa = new Scalar(1, 0, 0); //lower
    //	Scalar bb = new Scalar(255, 0, 0); //upper
    	/*}
    	else
    	{	//----------------sacar mascara de colores azules, q se supone son el objeto a segmentar
    		aa = new Scalar(0, 0, 1); //lower
    		bb = new Scalar(0, 0, 255); //upper
    	}*/
    	//----------------------------------------------
    	
    	//Mat msk = new Mat(nueva_imagen.height(),nueva_imagen.width(),CvType.CV_8UC1);
  /*  	Mat msk = new Mat(nueva_imagen.size(),nueva_imagen.type());
    	Core.inRange(nueva_imagen, aa, bb, msk);
    	
    	mostrar(msk, "localizar color");*/
    	
    	//guardarMatriz(msk, "msk.txt");
    	
    	
  /*  	List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    	Mat hiera = new Mat(msk.size(),msk.type());
    	Imgproc.findContours(msk, contours, hiera, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);*/
    	
    	
    	
   /* 	Mat dst = new Mat(nueva_imagen.size(), CvType.CV_8UC3);
    	Imgproc.drawContours(dst, contours, -1, new Scalar(255, 255, 255), Core.FILLED);
    	
    	mostrar(dst, "Contorno dibujado");
    	
    	
    	Mat resultado = new Mat(nueva_imagen.size(), CvType.CV_8UC3);
    	
    	Mat mat3 = new Mat(nueva_imagen.size(), CvType.CV_8UC3);*/
    	
    	
    //	Core.gemm(img, dst, 1, mat3, 0, resultado);
    	
    	//resultado=img.mul(dst);
    	
    	
    	
   // 	Core.gemm(mat2, mat1, 1, NULL, 0, mat3, 0);
    	
    	
    //	Core.multiply(nueva_imagen, dst, resultado); //solo me quedo con los contornos en nueva_imagen
    	
    	//mostrar(resultado, "resultado");
    	
    //	RotatedRect box = Imgproc.minAreaRect(points);
    	//Imgproc.minAreaRect(points)
    	
    	//Imgproc.GaussianBlur(nueva_imagen, nueva_imagen, new Size(5,5), 1);
    	
    
			Bitmap bmpOut = Bitmap.createBitmap(nueva_imagen.cols(),nueva_imagen.rows(),Bitmap.Config.ARGB_8888);
			
			
			//Rect roi = new Rect(50, 50, 100, 100);
			
			//Mat crop = new Mat(img, roi);
		//	Mat crop = new Mat(img, new Rect(0, 0, img.cols(), img.rows() / 2));
		//	Mat output = crop.clone();
			
			
			
			
			Utils.matToBitmap(nueva_imagen, bmpOut);
			return bmpOut;
	}
	
	
	/**
	 * Constantes para identificar la acción realizada (tomar una fotografía 
	 * o bien seleccionarla de la galería)
	 */
	private static int TAKE_PICTURE = 1;
	private static int SELECT_PICTURE = 2;
	
	/**
	 * Variable que define el nombre para el archivo donde escribiremos
	 * la fotografía de tamaño completo al tomarla.
	 */
	private String name = "";
	
    /** Este método es llamado cuando la actividad es creada */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack);
        
        setContentView(R.layout.activity_main);
        
       
      
        
        name = Environment.getExternalStorageDirectory() + "/test.jpg";
        
       resize = (CheckBox) findViewById(R.id.resize);
       size= (EditText) findViewById(R.id.size);
    	 resize.setChecked(true);

        Button btnAction = (Button)findViewById(R.id.btnPic);
        btnAction.setOnClickListener(new OnClickListener() {       		
       		public void onClick(View v) {
       			/**  
       			 * Obtenemos los botones de imagen completa y de galería para revisar su estatus
       			 * más adelante
       			 */
       		 //para  crear dinamicamente imagenes
       			if (layout!=null)
       				layout.removeAllViews();
                layout = (LinearLayout) findViewById(R.id.layout);
                i=0;
               
               
               
       			RadioButton rbtnFull = (RadioButton)findViewById(R.id.radbtnFull);
       			RadioButton rbtnGallery = (RadioButton)findViewById(R.id.radbtnGall);
       			
       			RadioButton foto1 = (RadioButton)findViewById(R.id.foto1);
       			RadioButton foto2 = (RadioButton)findViewById(R.id.foto2);
       			RadioButton foto3 = (RadioButton)findViewById(R.id.foto3);
       			
       			
       			
       			/**
       			 * Para todos los casos es necesario un intent, si accesamos la cámara con la acción
       			 * ACTION_IMAGE_CAPTURE, si accesamos la galería con la acción ACTION_PICK. 
       			 * En el caso de la vista previa (thumbnail) no se necesita más que el intent, 
       			 * el código e iniciar la actividad. Por eso inicializamos las variables intent y
       			 * code con los valores necesarios para el caso del thumbnail, así si ese es el
       			 * botón seleccionado no validamos nada en un if. 
       			 */
       			Intent intent =  new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
       			int code = TAKE_PICTURE;
       			
       			/**
       			 * Si la opción seleccionada es fotografía completa, necesitamos un archivo donde
       			 * guardarla
       			 */
       			if (rbtnFull.isChecked()) {					
       				Uri output = Uri.fromFile(new File(name));
       		    	intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
       		    	/**
           			 * Luego, con todo preparado iniciamos la actividad correspondiente.
           			 */
           			startActivityForResult(intent, code);	
       			/**
       			 * Si la opción seleccionada es ir a la galería, el intent es diferente y el código
       			 * también, en la consecuencia de que esté chequeado el botón de la galería se hacen
       			 * esas asignaciones
       			 */       		    	
       			} 
       			else if (rbtnGallery.isChecked()){       				
       				intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
       				code = SELECT_PICTURE;
       				
       				/**
           			 * Luego, con todo preparado iniciamos la actividad correspondiente.
           			 */
           			startActivityForResult(intent, code);	
       			}
       			
       			else if (foto1.isChecked()){       		
       				Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.cuadrado);
        			Bitmap salida = kmeans(bitmap);
        	    	bitmap.recycle();
       			}
       			else if (foto2.isChecked()){       		
       				Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.pelotas);
        			Bitmap salida = kmeans(bitmap);
        	    	bitmap.recycle();
       			}
				else if (foto3.isChecked()){       		
					
					Uri path = Uri.parse("android.resource://com.is.w2b/" + R.drawable.movil);
					InputStream is;
					try {
						is = getContentResolver().openInputStream(path);
						BufferedInputStream bis = new BufferedInputStream(is);
						Bitmap bitmap = BitmapFactory.decodeStream(bis);    
						Bitmap salida = kmeans(bitmap);
						bitmap.recycle();	
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					}
				}
       			
       						
       		}
       	});        
    }
    
    /**
     * Función que se ejecuta cuando concluye el intent en el que se solicita una imagen
     * ya sea de la cámara o de la galería
     */
    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	/**
    	 * Se revisa si la imagen viene de la cámara (TAKE_PICTURE) o de la galería (SELECT_PICTURE)
    	 */
    	if (requestCode == TAKE_PICTURE) {
    		/**
    		 * Si se reciben datos en el intent tenemos una vista previa (thumbnail)
    		 */
    		if (data != null) {
    			/**
    			 * En el caso de una vista previa, obtenemos el extra “data” del intent y 
    			 * lo mostramos en el ImageView
    			 */
    			if (data.hasExtra("data")) { 
    			//	ImageView iv = (ImageView)findViewById(R.id.imgView1);
    			//	iv.setImageBitmap((Bitmap) data.getParcelableExtra("data"));
    				Bitmap bitmap = (Bitmap) data.getParcelableExtra("data");
        			Bitmap salida = kmeans(bitmap);
        	    	bitmap.recycle();
    			}
    		/**
    		 * De lo contrario es una imagen completa
    		 */    			
    		} else {
    			/**
    			 * A partir del nombre del archivo ya definido lo buscamos y creamos el bitmap
    			 * para el ImageView
    			 */
    			//ImageView iv = (ImageView)findViewById(R.id.imgView1);
    		//	iv.setImageBitmap(BitmapFactory.decodeFile(name));
    			Bitmap bitmap = BitmapFactory.decodeFile(name);  
    			Bitmap salida = kmeans(bitmap);
    	    	bitmap.recycle();
    			/**  
    			 * Para guardar la imagen en la galería, utilizamos una conexión a un MediaScanner
    			 */
    			new MediaScannerConnectionClient() {
    				private MediaScannerConnection msc = null; {
    					msc = new MediaScannerConnection(getApplicationContext(), this); msc.connect();
    				}
    				public void onMediaScannerConnected() { 
    					msc.scanFile(name, null);
    				}
    				public void onScanCompleted(String path, Uri uri) { 
    					msc.disconnect();
    				} 
    			};				
    		}
    	/**
    	 * Recibimos el URI de la imagen y construimos un Bitmap a partir de un stream de Bytes
    	 */
    	} else if (requestCode == SELECT_PICTURE){
    		Uri selectedImage = data.getData();
    		InputStream is;
    		try {
    			is = getContentResolver().openInputStream(selectedImage);
    	    	BufferedInputStream bis = new BufferedInputStream(is);
    	    	Bitmap bitmap = BitmapFactory.decodeStream(bis);    
    	    	
    	  
    	//    	ImageView iv = (ImageView)findViewById(R.id.imgView1);
    	    	//Mat img = new Mat(bitmap.getHeight(),bitmap.getWidth(),CvType.CV_8UC3);
    	        
    	      
    	    
    	    	Bitmap salida = kmeans(bitmap);
    	    	bitmap.recycle();
    	    
    	    	

    	    	
    	    	
    	    	
    	    //	iv.setImageBitmap(salida);	
    	    	
    	    	
    	   
    		} catch (FileNotFoundException e) {}
    	}
    }
    
    public Boolean contarPixels(Mat img) // true si rojos>azules
    {
    	int i=0;
    	int j=0;
    	//int z=0;
    	double buffaux[] = new double[3];
    	int contRojo = 0;
    	int contAzul = 0;
    	
    	
    	for(i=0; i<img.rows(); i++)
			{
			
				for(j=0; j<img.cols(); j++)
				{
					
						
						buffaux = img.get(i, j);
						
						if (buffaux[0] == 255.0){
							contRojo++;
						}
						if (buffaux[2] == 255.0){
							contAzul++;
						}
						
						
						
					
				}
			}	
    	
    	if (contRojo > contAzul){ 
    		return true;
    		}
    	return false;
    }
    
    
    private void guardarMatriz(Mat img, String nombreFichero) {
		//inicializo todo fichero a 0, solo deberia entrar aqui la primera vez q se juega
		//fichero en SD que contiene el estado de cada marca: 0-> no intentado, 1->fallado, 2-> Acertado
		
		double buffaux[] = new double[3];
		
		boolean sdDisponible = false;
		boolean sdAccesoEscritura = false;
		
		int numeroCanales = 3;
		if(img.channels()==1) numeroCanales = 1;
		if(img.channels()==2) numeroCanales = 2;
		
		
		
		//Comprobamos el estado de la memoria externa (tarjeta SD)
		String estado = Environment.getExternalStorageState();

		if (estado.equals(Environment.MEDIA_MOUNTED))
		{
			sdDisponible = true;
			sdAccesoEscritura = true;
		} 
		else if (estado.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
		{
			sdDisponible = true;
			sdAccesoEscritura = false;
		} 
		else 
		{
			sdDisponible = false;
			sdAccesoEscritura = false;
		}
		
		//Si la memoria externa est· disponible y se puede escribir
		if (sdDisponible && sdAccesoEscritura)
		{
			try
			{
				File ruta_sd = Environment.getExternalStorageDirectory();
				
				File f = new File(ruta_sd.getAbsolutePath(), nombreFichero);
				
					OutputStreamWriter fout = new OutputStreamWriter(new FileOutputStream(f));
					int i =0;
					int j=0;
					int z=0;
					
					for(i=0; i<img.rows(); i++)
	   				{
						fout.write("\n");
						fout.write("\n");
	   					for(j=0; j<img.cols(); j++)
	   					{
	   						buffaux = img.get(i, j);
	   						for(z=0; z<numeroCanales; z++){
	   							
	   							
	   							//samples.put(i + j*entrada.rows(), z, buffaux[z]);
	   							//fout.write("i: "+String.valueOf(i)+" j: "+String.valueOf(j)+" z: "+String.valueOf(z));
	   							fout.write(String.valueOf(buffaux[z])+" ");
	   							//System.out.println("hola");
	   							
	   						}
	   					}
	   				}	
					
					/*for(int i=0;i<this.numeroMarcas;i++){
						fout.write("0");
						fout.write("\n");
					}*/
					//fout.write("Texto de prueba.");
					fout.close();
				//	Toast.makeText(this, "iniciar ficheroSD", Toast.LENGTH_LONG).show();
					//txtResultado.setText("Fichero SD creado!");
				
			}
			catch (Exception ex)
			{
				Log.e("Ficheros", "Error al escribir fichero a tarjeta SD");
			}
		}
	}


    
}